<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>UI Datepicker Tests</title>
<link rel="Stylesheet" media="screen" href="../../../jquery/test/data/testsuite.css" />
<style type="text/css">@import "../core/ui.datepicker.css";</style>
<script type="text/javascript" src="../core/jquery.js"></script>
<script type="text/javascript" src="../../../jquery/test/data/testrunner.js"></script>
<script type="text/javascript" src="../core/ui.datepicker.js"></script>
<script type="text/javascript">
$(function() {
	test('setDefaults', function() {
		init();
		expect(2);
		equals($.datepicker._defaults.showOn, 'focus', 'Initial showOn');
		$.datepicker.setDefaults({showOn: 'both'});
		equals($.datepicker._defaults.showOn, 'both', 'Changed showOn');
		$.datepicker.setDefaults({showOn: 'focus'});
	});

	test('remove', function() {
		init();
		expect(6);
		var rem = $('#rem');
		ok(rem[0]._calId != undefined && rem[0]._calId != null, 'ID present');
		ok(rem.parent('.datepicker_wrap').length > 0, 'Wrapper present');
		ok(rem.is('.hasDatepicker'), 'Marker class present');
		rem.datepicker('destroy');
		rem = $('#rem');
		ok(rem[0]._calId == undefined || rem[0]._calId == null, 'ID gone');
		ok(!(rem.parent('.datepicker_wrap').length > 0), 'Wrapper gone');
		ok(!(rem.is('.hasDatepicker')), 'Marker class gone');
	});

	test('disableEnable', function() {
		init();
		expect(3);
		var dp = $('#dp');
		ok(!(dp.datepicker('isDisabled')), 'Control is enabled');
		dp.datepicker('disable');
		ok(dp.datepicker('isDisabled'), 'Control is disabled');
		dp.datepicker('enable');
		ok(!(dp.datepicker('isDisabled')), 'Control is enabled again');
	});

	test('change', function() {
		init();
		expect(9);
		var dp = $('#dp');
		var inst = $.datepicker._inst[dp[0]._calId];
		equals(inst._settings.clearText, 'Erase', 'Change clearText');
		dp.datepicker('change', {clearText: 'X1'});
		equals(inst._settings.clearText, 'X1', 'Change clearText');
		dp.datepicker('change', {clearText: 'X2'});
		equals(inst._settings.clearText, 'X2', 'Change clearText');
		$('#dp:first').datepicker('change', {clearText: 'X3'});
		equals(inst._settings.clearText, 'X3', 'Change clearText');
		$('#dp:first').datepicker('change', {clearText: null});
		ok(inst._settings.clearText == null, 'Change clearText');
		dp.datepicker('change', {clearText: 'Erase'});
		equals(inst._settings.clearText, 'Erase', 'Change clearText');
		dp.datepicker('change', 'clearText', 'X1');
		equals(inst._settings.clearText, 'X1', 'Change clearText');
		$('#dp:first').datepicker('change', 'clearText', null);
		ok(inst._settings.clearText == null, 'Change clearText');
		dp.datepicker('change', 'clearText', 'Erase');
		equals(inst._settings.clearText, 'Erase', 'Change clearText');
	});

	test('setGetDate', function() {
		init();
		expect(2);
		var dp = $('#dp');
		ok(dp.datepicker('getDate') == null, 'Default date set');
		var date = new Date(2001, 2 - 1, 3);
		dp.datepicker('setDate', date);
		equals(dp.datepicker('getDate').toString(), date.toString(), 'Date set');
	});

	test('noWeekends', function() {
		init();
		expect(28);
		for (var d = 0; d < 28; d++) {
			isSet($.datepicker.noWeekends(new Date(2007, 12 - 1, d + 1)), 
				[(d % 7) > 1, ''], 'Weekend options for ' + (d + 1) + '/12/2007');
		}
	});

	test('iso8601Week', function() {
		init();
		var weeks = [[new Date(2007, 12 - 1, 30), 52], [new Date(2007, 12 - 1, 31), 1],
			[new Date(2008, 1 - 1, 1), 1], [new Date(2008, 1 - 1, 6), 1],
			[new Date(2008, 1 - 1, 7), 2], [new Date(2008, 3 - 1, 24), 13],
			[new Date(2008, 3 - 1, 31), 14], [new Date(2008, 7 - 1, 10), 28],
			[new Date(2008, 12 - 1, 28), 52], [new Date(2008, 12 - 1, 29), 1],
			[new Date(2008, 12 - 1, 31), 1], [new Date(2009, 1 - 1, 1), 1],
			[new Date(2009, 12 - 1, 27), 52], [new Date(2009, 12 - 1, 28), 53],
			[new Date(2009, 12 - 1, 31), 53], [new Date(2010, 1 - 1, 1), 53],
			[new Date(2010, 1 - 1, 3), 53], [new Date(2010, 1 - 1, 4), 1]];
		expect(weeks.length);
		for (var i = 0; i < weeks.length; i++) {
			equals($.datepicker.iso8601Week(weeks[i][0]), weeks[i][1],
				'ISO week for ' + weeks[i][0]);
		}
	});

	test('parseDate', function() {
		init();
		expect(15);
		var date = new Date(2007, 6 - 1, 5);
		ok($.datepicker.parseDate('dd/mm/yy', '') == null, 'Parsed date - blank');
		dateEquals($.datepicker.parseDate('dd/mm/yy', '05/06/2007'), date,
			'Parsed date - dd/mm/yy');
		dateEquals($.datepicker.parseDate('d/m/yy', '5/6/2007'), date,
			'Parsed date - d/m/yy');
		dateEquals($.datepicker.parseDate('dd/mm/yy', '5/6/2007'), date,
			'Parsed date - dd/mm/yy (2)');
		dateEquals($.datepicker.parseDate('d/m/yy', '05/06/2007'), date,
			'Parsed date - d/m/yy (2)');
		dateEquals($.datepicker.parseDate('yy-mm-dd', '2007-06-05'), date,
			'Parsed date - yy-mm-dd');
		dateEquals($.datepicker.parseDate('ddMyy', '05Jun2007'), date,
			'Parsed date - ddMyy');
		dateEquals($.datepicker.parseDate('DD, MM d, yy', 'Tuesday, June 5, 2007'), date,
			'Parsed date - DD, MM d, yy');
		dateEquals($.datepicker.parseDate('dd\'\'mm\'\'yy', '05\'06\'2007'), date,
			'Parsed date - dd\'\'mm\'\'yy');
		dateEquals($.datepicker.parseDate('\'Day\' d of MM in the \'year\' yy',
			'Day 5 of June in the year 2007'), date,
			'Parsed date - \'Day\' d of MM in the \'year\' yy');
		dateEquals($.datepicker.parseDate('D M dd yy', 'Tue Jun 05 2007'), date,
			'Parsed date - D M dd yy');
		// check short year
		dateEquals($.datepicker.parseDate('dd/mm/y', '05/06/07', {shortYearCutoff: 10}),
			date, 'Parsed date - dd/mm/y (< cutoff)');
		dateEquals($.datepicker.parseDate('dd/mm/y', '05/06/07', {shortYearCutoff: 5}),
			new Date(1907, 6 - 1, 5), 'Parsed date - dd/mm/y (> cutoff)');
		// other language
		dateEquals($.datepicker.parseDate('DddMyy', 'dth05msi2007', {shortYearCutoff: 10,
			dayNamesShort: ['don', 'dtw', 'dth', 'dfo', 'dfi', 'dsi', 'dse'],
			dayNames: ['done', 'dtwo', 'dthree', 'dfour', 'dfive', 'dsix', 'dseven'],
			monthNamesShort: ['mon', 'mtw', 'mth', 'mfo', 'mfi', 'msi',
			'mse', 'mei', 'mni', 'mte', 'mel', 'mtv'],
			monthNames: ['mone', 'mtwo', 'mthree', 'mfour', 'mfive', 'msix',
			'mdseven', 'meight', 'mnine', 'mten', 'meleven', 'mtwelve']}),
			date, 'Parsed date - DddMyy (language)');
		dateEquals($.datepicker.parseDate('DD dd MM yy', 'dthree 05 msix 2007', {shortYearCutoff: 10,
			dayNamesShort: ['don', 'dtw', 'dth', 'dfo', 'dfi', 'dsi', 'dse'],
			dayNames: ['done', 'dtwo', 'dthree', 'dfour', 'dfive', 'dsix', 'dseven'],
			monthNamesShort: ['mon', 'mtw', 'mth', 'mfo', 'mfi', 'msi',
			'mse', 'mei', 'mni', 'mte', 'mel', 'mtv'],
			monthNames: ['mone', 'mtwo', 'mthree', 'mfour', 'mfive', 'msix',
			'mdseven', 'meight', 'mnine', 'mten', 'meleven', 'mtwelve']}),
			date, 'Parsed date - DD dd MM yy (language)');
	});

	test('parseDateErrors', function() {
		init();
		expect(12);
		try {
			$.datepicker.parseDate(null, '05/06/2007');
			ok(false, 'Parsed null format argument');
		}
		catch (e) {
			equals(e, 'Invalid arguments', 'Invalid arguments - null format');
		}
		try {
			$.datepicker.parseDate('dd/mm/yy', null);
			ok(false, 'Parsed null value argument');
		}
		catch (e) {
			equals(e, 'Invalid arguments', 'Invalid arguments - null value');
		}
		try {
			$.datepicker.parseDate('dd-mm-yy', '05/06/2007');
			ok(false, 'Parsed invalid format - dd-mm-yy');
		}
		catch (e) {
			equals(e, 'Unexpected literal at position 2',
				'Unexpected literal - 05/06/2007');
		}
		try {
			$.datepicker.parseDate('dMyy', '05Jum2007');
			ok(false, 'Parsed invalid format - dMyy');
		}
		catch (e) {
			equals(e, 'Unknown name at position 2', 'Unknown name - 05Jum2007');
		}
		try {
			$.datepicker.parseDate('\'Day\' d of MM in the \'year\' yy',
				'Day 5 ov June in the year 2007');
			ok(false, 'Parsed invalid format - \'Day\' d of MM in the \'year\' yy');
		}
		catch (e) {
			equals(e, 'Unexpected literal at position 7',
				'Unexpected literal - Day 5 ov June in the year 2007');
		}
		try {
			$.datepicker.parseDate('dd/mm/yy', '31/02/2007');
			ok(false, 'Parsed invalid date - dd/mm/yy');
		}
		catch (e) {
			equals(e, 'Invalid date', 'Invalid date - 31/02/2007');
		}
		try {
			$.datepicker.parseDate('dd/mm/yy', 'not a date');
			ok(false, 'Parsed non-date string');
		}
		catch (e) {
			equals(e, 'Missing number at position 0', 'Missing number - not a date');
		}
		try {
			$.datepicker.parseDate('dd/mm/yy', new Date(2007, 6 - 1, 5));
			ok(false, 'Parsed date object');
		}
		catch (e) {
			equals(e, 'Missing number at position 0', 'Missing number - new Date()');
		}
		// other language
		try {
			$.datepicker.parseDate('DddMyy', 'dze05msi2007', {shortYearCutoff: 10,
				dayNamesShort: ['don', 'dtw', 'dth', 'dfo', 'dfi', 'dsi', 'dse'],
				dayNames: ['done', 'dtwo', 'dthree', 'dfour', 'dfive', 'dsix', 'dseven'],
				monthNamesShort: ['mon', 'mtw', 'mth', 'mfo', 'mfi', 'msi',
				'mse', 'mei', 'mni', 'mte', 'mel', 'mtv'],
				monthNames: ['mone', 'mtwo', 'mthree', 'mfour', 'mfive', 'msix',
				'mdseven', 'meight', 'mnine', 'mten', 'meleven', 'mtwelve']});
			ok(false, 'Parsed invalid format - DddMyy (1)');
		}
		catch (e) {
			equals(e, 'Unknown name at position 0', 'Unknown name - dze05msi2007');
		}
		try {
			$.datepicker.parseDate('DddMyy', 'dth05mze2007', {shortYearCutoff: 10,
				dayNamesShort: ['don', 'dtw', 'dth', 'dfo', 'dfi', 'dsi', 'dse'],
				dayNames: ['done', 'dtwo', 'dthree', 'dfour', 'dfive', 'dsix', 'dseven'],
				monthNamesShort: ['mon', 'mtw', 'mth', 'mfo', 'mfi', 'msi',
				'mse', 'mei', 'mni', 'mte', 'mel', 'mtv'],
				monthNames: ['mone', 'mtwo', 'mthree', 'mfour', 'mfive', 'msix',
				'mdseven', 'meight', 'mnine', 'mten', 'meleven', 'mtwelve']});
			ok(false, 'Parsed invalid format - DddMyy (2)');
		}
		catch (e) {
			equals(e, 'Unknown name at position 5', 'Unknown name - dth05mze2007');
		}
		try {
			$.datepicker.parseDate('DD dd MM yy', 'dzero 05 msix 2007', {shortYearCutoff: 10,
				dayNamesShort: ['don', 'dtw', 'dth', 'dfo', 'dfi', 'dsi', 'dse'],
				dayNames: ['done', 'dtwo', 'dthree', 'dfour', 'dfive', 'dsix', 'dseven'],
				monthNamesShort: ['mon', 'mtw', 'mth', 'mfo', 'mfi', 'msi',
				'mse', 'mei', 'mni', 'mte', 'mel', 'mtv'],
				monthNames: ['mone', 'mtwo', 'mthree', 'mfour', 'mfive', 'msix',
				'mdseven', 'meight', 'mnine', 'mten', 'meleven', 'mtwelve']});
			ok(false, 'Parsed invalid format - DD dd MM yy (1)');
		}
		catch (e) {
			equals(e, 'Unknown name at position 0', 'Unknown name - dzero 05 msix 2007');
		}
		try {
			$.datepicker.parseDate('DD dd MM yy', 'dthree 05 mzero 2007', {shortYearCutoff: 10,
				dayNamesShort: ['don', 'dtw', 'dth', 'dfo', 'dfi', 'dsi', 'dse'],
				dayNames: ['done', 'dtwo', 'dthree', 'dfour', 'dfive', 'dsix', 'dseven'],
				monthNamesShort: ['mon', 'mtw', 'mth', 'mfo', 'mfi', 'msi',
				'mse', 'mei', 'mni', 'mte', 'mel', 'mtv'],
				monthNames: ['mone', 'mtwo', 'mthree', 'mfour', 'mfive', 'msix',
				'mdseven', 'meight', 'mnine', 'mten', 'meleven', 'mtwelve']});
			ok(false, 'Parsed invalid format - DD dd MM yy (2)');
		}
		catch (e) {
			equals(e, 'Unknown name at position 10', 'Unknown name - dthree 05 mzero 2007');
		}
	});

	test('formatDate', function() {
		init();
		expect(10);
		var date = new Date(2007, 6 - 1, 5);
		equals($.datepicker.formatDate('dd/mm/yy', null), '', 'Formatted date - null');
		equals($.datepicker.formatDate('dd/mm/yy', date), '05/06/2007', 'Formatted date - dd/mm/yy');
		equals($.datepicker.formatDate('d/m/y', date), '5/6/07', 'Formatted date - d/m/y');
		equals($.datepicker.formatDate('yy-mm-dd', date), '2007-06-05', 'Formatted date - yy-mm-dd');
		equals($.datepicker.formatDate('ddMyy', date), '05Jun2007', 'Formatted date - ddMyy');
		equals($.datepicker.formatDate('DD, MM d, yy', date), 'Tuesday, June 5, 2007',
			'Formatted date - DD, MM d, yy');
		equals($.datepicker.formatDate('dd\'\'mm\'\'yy', date), '05\'06\'2007',
			'Formatted date - dd\'\'mm\'\'yy');
		equals($.datepicker.formatDate('\'Day\' d of MM in the \'year\' yy', date),
			'Day 5 of June in the year 2007',
			'Formatted date - \'Day\' d of MM in the \'year\' yy');
		// other language
		equals($.datepicker.formatDate('DddMyy', date,
			{dayNamesShort: ['don', 'dtw', 'dth', 'dfo', 'dfi', 'dsi', 'dse'],
			dayNames: ['done', 'dtwo', 'dthree', 'dfour', 'dfive', 'dsix', 'dseven'],
			monthNamesShort: ['mon', 'mtw', 'mth', 'mfo', 'mfi', 'msi',
			'mse', 'mei', 'mni', 'mte', 'mel', 'mtv'],
			monthNames: ['mone', 'mtwo', 'mthree', 'mfour', 'mfive', 'msix',
			'mdseven', 'meight', 'mnine', 'mten', 'meleven', 'mtwelve']}),
			'dth05msi2007', 'Formatted date - ddMyy (language)');
		equals($.datepicker.formatDate('DD dd MM yy', date,
			{dayNamesShort: ['don', 'dtw', 'dth', 'dfo', 'dfi', 'dsi', 'dse'],
			dayNames: ['done', 'dtwo', 'dthree', 'dfour', 'dfive', 'dsix', 'dseven'],
			monthNamesShort: ['mon', 'mtw', 'mth', 'mfo', 'mfi', 'msi',
			'mse', 'mei', 'mni', 'mte', 'mel', 'mtv'],
			monthNames: ['mone', 'mtwo', 'mthree', 'mfour', 'mfive', 'msix',
			'mdseven', 'meight', 'mnine', 'mten', 'meleven', 'mtwelve']}),
			'dthree 05 msix 2007', 'Formatted date - DD dd MM yy (language)');
	});

	test('get', function() {
		init();
		expect(2);
		equals($.datepicker._defaults.clearText, 'Clear', 'Default clearText');
		equals($.datepicker._inst[$('#dp')[0]._calId]._settings.clearText,
			'Erase', 'Instance clearText');
	});

	test('getDefaultDate', function() {
		init();
		expect(21);
		var dp = $('#dp');
		var inst = $.datepicker._inst[dp[0]._calId];
		dateEquals(inst._getDefaultDate(), new Date(), 'Default date - today');
		// as date
		var date = new Date(2007, 6 - 1, 5);
		dp.datepicker('change', {defaultDate: date});
		dateEquals(inst._getDefaultDate(), date, 'Default date - 2007-06-05');
		dp.datepicker('change', {defaultDate: null});
		dateEquals(inst._getDefaultDate(), new Date(), 'Default date - reset');
		// as relative numeric offsets
		dp.datepicker('change', {defaultDate: +7});
		dateEquals(inst._getDefaultDate(), offsetDate(7), 'Default date - +7');
		dp.datepicker('change', {defaultDate: -7});
		dateEquals(inst._getDefaultDate(), offsetDate(-7), 'Default date - -7');
		// as relative string offsets
		dp.datepicker('change', {defaultDate: '1'});
		dateEquals(inst._getDefaultDate(), offsetDate(1), 'Default date - 1');
		dp.datepicker('change', {defaultDate: '1d'});
		dateEquals(inst._getDefaultDate(), offsetDate(1), 'Default date - 1d');
		dp.datepicker('change', {defaultDate: '+1  d'});
		dateEquals(inst._getDefaultDate(), offsetDate(1), 'Default date - +1  d');
		dp.datepicker('change', {defaultDate: '-1 D'});
		dateEquals(inst._getDefaultDate(), offsetDate(-1), 'Default date - -1 D');
		dp.datepicker('change', {defaultDate: '2w'});
		dateEquals(inst._getDefaultDate(), offsetDate(14), 'Default date - 2w');
		dp.datepicker('change', {defaultDate: '+2  w'});
		dateEquals(inst._getDefaultDate(), offsetDate(14), 'Default date - +2  w');
		dp.datepicker('change', {defaultDate: '-2 W'});
		dateEquals(inst._getDefaultDate(), offsetDate(-14), 'Default date - -2 W');
		dp.datepicker('change', {defaultDate: '3m'});
		dateEquals(inst._getDefaultDate(), offsetMonth(3), 'Default date - 3m');
		dp.datepicker('change', {defaultDate: '+3  m'});
		dateEquals(inst._getDefaultDate(), offsetMonth(3), 'Default date - +3  m');
		dp.datepicker('change', {defaultDate: '-3 M'});
		dateEquals(inst._getDefaultDate(), offsetMonth(-3), 'Default date - -3 M');
		dp.datepicker('change', {defaultDate: '4y'});
		dateEquals(inst._getDefaultDate(), offsetMonth(48), 'Default date - 4y');
		dp.datepicker('change', {defaultDate: '+4  y'});
		dateEquals(inst._getDefaultDate(), offsetMonth(48), 'Default date - +4  y');
		dp.datepicker('change', {defaultDate: '-4 Y'});
		dateEquals(inst._getDefaultDate(), offsetMonth(-48), 'Default date - -4 Y');
		// as error offsets
		date = new Date();
		dp.datepicker('change', {defaultDate: '2days'});
		dateEquals(inst._getDefaultDate(), date, 'Default date - 2days');
		dp.datepicker('change', {defaultDate: 'now'});
		dateEquals(inst._getDefaultDate(), date, 'Default date - now');
		dp.datepicker('change', {defaultDate: '2f'});
		dateEquals(inst._getDefaultDate(), date, 'Default date - 2f');
	});

	test('adjustDate', function() {
		init();
		expect(16 + 12 + 12);
		var adj = $('#adj');
		var inst = $.datepicker._inst[adj[0]._calId];
		inst._rangeStart = null;
		adj.datepicker('change', {minDate: null, maxDate: null}).
			datepicker('setDate', new Date(2001, 2 - 1, 3));
		var adjusts = [[0, 'D', 2001, 2, 3], [1, 'D', 2001, 2, 4],
			[7, 'D', 2001, 2, 11], [-8, 'D', 2001, 2, 3],
			[-8, 'D', 2001, 1, 26], [+5, 'D', 2001, 1, 31],
			[0, 'M', 2001, 1, 31], [1, 'M', 2001, 2, 28],
			[13, 'M', 2002, 3, 28], [-3, 'M', 2001, 12, 28],
			[26, 'M', 2004, 2, 28], [1, 'D', 2004, 2, 29],
			[0, 'Y', 2004, 2, 29], [1, 'Y', 2005, 2, 28],
			[11, 'Y', 2016, 2, 28], [-12, 'Y', 2004, 2, 28]];
		for (var i = 0; i < adjusts.length; i++) {
			inst._adjustDate(adjusts[i][0], adjusts[i][1]);
			dateEquals(new Date(inst._selectedYear, inst._selectedMonth, inst._selectedDay),
				new Date(adjusts[i][2], adjusts[i][3] - 1, adjusts[i][4]),
				'Date adjustment ' + adjusts[i][0] + ' ' + adjusts[i][1]);
		}
		// with minimum
		adj.datepicker('change', {minDate: new Date(2001, 1 - 1, 1)}).
			datepicker('setDate', new Date(2001, 2 - 1, 3));
		adjusts = [[0, 'D', 2001, 2, 3], [7, 'D', 2001, 2, 10],
			[-88, 'D', 2001, 1, 1], [5, 'D', 2001, 1, 6],
			[0, 'M', 2001, 1, 6], [13, 'M', 2002, 2, 6],
			[-20, 'M', 2001, 1, 1], [1, 'M', 2001, 2, 1],
			[0, 'Y', 2001, 2, 1], [6, 'Y', 2007, 2, 1],
			[-11, 'Y', 2001, 1, 1], [2, 'Y', 2003, 1, 1]];
		for (var i = 0; i < adjusts.length; i++) {
			inst._adjustDate(adjusts[i][0], adjusts[i][1]);
			dateEquals(new Date(inst._selectedYear, inst._selectedMonth, inst._selectedDay),
				new Date(adjusts[i][2], adjusts[i][3] - 1, adjusts[i][4]),
				'Date adjustment (min) ' + adjusts[i][0] + ' ' + adjusts[i][1]);
		}
		// with maximum
		adj.datepicker('change', {minDate: null, maxDate: new Date(2001, 6 - 1, 30)}).
			datepicker('setDate', new Date(2001, 2 - 1, 3));
		adjusts = [[0, 'D', 2001, 2, 3], [7, 'D', 2001, 2, 10],
			[200, 'D', 2001, 6, 30], [-184, 'D', 2000, 12, 28],
			[0, 'M', 2000, 12, 28], [3, 'M', 2001, 3, 28],
			[6, 'M', 2001, 6, 30], [-5, 'M', 2001, 1, 30],
			[0, 'Y', 2001, 1, 30], [6, 'Y', 2001, 6, 30],
			[-11, 'Y', 1990, 6, 30], [2, 'Y', 1992, 6, 30]];
		for (var i = 0; i < adjusts.length; i++) {
			inst._adjustDate(adjusts[i][0], adjusts[i][1]);
			dateEquals(new Date(inst._selectedYear, inst._selectedMonth, inst._selectedDay),
				new Date(adjusts[i][2], adjusts[i][3] - 1, adjusts[i][4]),
				'Date adjustment (max) ' + adjusts[i][0] + ' ' + adjusts[i][1]);
		}
	});

	test('getNumberOfMonths', function() {
		init();
		expect(4);
		var dp = $('#dp');
		var inst = $.datepicker._inst[dp[0]._calId];
		isSet(inst._getNumberOfMonths(), [1, 1], 'Number of months (default)');
		dp.datepicker('change', {numberOfMonths: null});
		isSet(inst._getNumberOfMonths(), [1, 1], 'Number of months (null)');
		dp.datepicker('change', {numberOfMonths: 2});
		isSet(inst._getNumberOfMonths(), [1, 2], 'Number of months (2)');
		dp.datepicker('change', {numberOfMonths: [3, 4]});
		isSet(inst._getNumberOfMonths(), [3, 4], 'Number of months (3,4)');
		dp.datepicker('change', {numberOfMonths: 1});
	});

	test('getMinMaxDate', function() {
		init();
		expect(18);
		var adj = $('#adj');
		var inst = $.datepicker._inst[adj[0]._calId];
		adj.datepicker('change', {minDate: null, maxDate: null});
		ok(inst._getMinMaxDate('min') == null, 'Min date (null)');
		ok(inst._getMinMaxDate('min', false) == null, 'Min date (null,false)');
		ok(inst._getMinMaxDate('min', true) == undefined, 'Min date (null,true)');
		ok(inst._getMinMaxDate('max') == null, 'Max date (null)');
		var date = new Date();
		date = new Date(date.getFullYear(), date.getMonth(), date.getDate());
		adj.datepicker('change', {minDate: new Date()});
		dateEquals(inst._getMinMaxDate('min'), date, 'Min date');
		dateEquals(inst._getMinMaxDate('min', false), date, 'Min date (false)');
		dateEquals(inst._getMinMaxDate('min', true), date, 'Min date (true)');
		inst._rangeStart = new Date(date.getFullYear(), date.getMonth(), date.getDate() + 7);
		dateEquals(inst._getMinMaxDate('min', false), date, 'Min date (range,false)');
		dateEquals(inst._getMinMaxDate('min', true), date, 'Min date (range,true)');
		adj.datepicker('change', {maxDate: new Date()});
		dateEquals(inst._getMinMaxDate('max'), date, 'Max date');
		adj.datepicker('change', {minDate: null});
		ok(inst._getMinMaxDate('min', false) == null, 'Min date (null,range,false)');
		dateEquals(inst._getMinMaxDate('min', true), inst._rangeStart,
			'Min date (null,range,true)');
		// as relative numeric offsets
		adj.datepicker('change', {minDate: -7});
		dateEquals(inst._getMinMaxDate('min'), offsetDate(-7), 'Min date (-7)');
		adj.datepicker('change', {maxDate: +14});
		dateEquals(inst._getMinMaxDate('max'), offsetDate(14), 'Max date (+14)');
		// as relative string offsets
		adj.datepicker('change', {minDate: '3 w'});
		dateEquals(inst._getMinMaxDate('min'), offsetDate(21), 'Min date (3 w)');
		adj.datepicker('change', {maxDate: '2M'});
		dateEquals(inst._getMinMaxDate('max'), offsetMonth(2), 'Max date (2M)');
		// as error offsets
		date = new Date();
		adj.datepicker('change', {minDate: 'now'});
		dateEquals(inst._getMinMaxDate('min'), date, 'Min date (now)');
		adj.datepicker('change', {maxDate: '2f'});
		dateEquals(inst._getMinMaxDate('max'), date, 'Max date (2f)');
	});

	test('getFirstDayOfMonth', function() {
		init();
		expect(12);
		var inst = $.datepicker._inst[$('#dp')[0]._calId];
		var fd = [1, 4, 4, 0, 2, 5, 0, 3, 6, 1, 4, 6];
		for (var m = 0; m < 12; m++) { 
			equals(inst._getFirstDayOfMonth(2007, m), fd[m],
				'First day of month for ' + (m + 1) + '/2007');
		}
	});

	test('getDaysInMonth', function() {
		init();
		expect(24);
		var inst = $.datepicker._inst[$('#dp')[0]._calId];
		var md = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
		for (var y = 2007; y < 2009; y++) {
			for (var m = 0; m < 12; m++) { 
				equals(inst._getDaysInMonth(y, m),
					(m == 1 ? (y == 2007 ? 28 : 29) : md[m]),
					'Days in month for ' + (m + 1) + '/' + y);
			}
		}
	});
});	

function init() {
	$('#dp').datepicker({clearText: 'Erase'});
	$('#adj').datepicker();
	$('#rem').datepicker({showOn: 'both'});
}

function offsetDate(offset) {
	var date = new Date();
	date.setDate(date.getDate() + offset);
	return date;
}

function offsetMonth(offset) {
	var date = new Date();
	date.setDate(Math.min(date.getDate(),
		$.datepicker._inst[$('#dp')[0]._calId]._getDaysInMonth(
		date.getFullYear(), date.getMonth() + offset)));
	date.setMonth(date.getMonth() + offset);
	return date;
}

function dateEquals(date1, date2, msg) {
	if (date1 == null || date2 == null) {
		ok(false, msg + ' - null dates');
		return;
	}
	date1.setHours(0);
	date1.setMinutes(0);
	date1.setSeconds(0);
	date1.setMilliseconds(0);
	date2.setHours(0);
	date2.setMinutes(0);
	date2.setSeconds(0);
	date2.setMilliseconds(0);
	equals(date1.toString(), date2.toString(), msg);
}
</script>
</head>

<body>
<h1>UI Datepicker Tests</h1>

<p>This page contains unit tests for the UI Datepicker plugin.
	To see them, take a look at the source.</p>
<ol id="tests">
</ol>
<div id="main" style="display: none;">
	<p><input type="text" id="dp"/></p>
	<p><input type="text" id="adj"/></p>
	<p><input type="text" id="rem"/></p>
</div>
</body>
</html>
